package com.sanyuan.cloud.module.system.service.nongmo.impl;

import cn.hutool.core.collection.CollUtil;
import com.sanyuan.cloud.module.system.dal.dataobject.nongmo.SystemPositionDO;
import com.sanyuan.cloud.module.system.dal.mysql.nongmo.SystemPositionMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;

import static com.sanyuan.cloud.module.system.enums.nongmo.NongmoRedisKeyConstants.GEO_KEY;

/**
 * @Description:
 * @Author: wuyuwei
 * @Date: 2025/3/28
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GeoSyncService {
    private final SystemPositionMapper positionMapper;
    private final RedisTemplate<String, Object> redisTemplate;



    /**
     * 初始化同步所有数据
     */
    @PostConstruct
    public void initSyncToRedis() {
        List<SystemPositionDO> positions = positionMapper.selectList(null);
        if (CollUtil.isEmpty(positions)){
            return;
        }
        positions.forEach(pos -> {
            if (!pos.getDeleted()) {
                addToRedis(pos);
            }
        });
    }

    /**
     * 添加单个位置到Redis
     * @param pos
     */
    public void addToRedis(SystemPositionDO pos) {
        log.info("--- addToRedis pos:{}",pos);
        // 1. 参数顺序：经度 → 纬度
        double longitude = Double.parseDouble(pos.getLongitude());
        double latitude = Double.parseDouble(pos.getLatitude());

        // 2. 校验范围
        if (longitude < -180 || longitude > 180) {
            throw new IllegalArgumentException("Invalid longitude: " + longitude);
        }
        if (latitude < -85.05112878 || latitude > 85.05112878) {
            throw new IllegalArgumentException("Invalid latitude: " + latitude);
        }

        // 3. 添加数据到 Redis
        redisTemplate.opsForGeo().add(
                GEO_KEY,
                new RedisGeoCommands.GeoLocation<>(
                        pos.getId(),
                        // 经度在前
                        new Point(longitude, latitude)
                )
        );
    }

    /**
     * 从Redis移除位置
     * @param id
     */
    public void removeFromRedis(Long id) {
        redisTemplate.opsForGeo().remove(GEO_KEY, id);
    }
}